Skip to content

Generate the API reference from the declarations that ship - #13

Merged
tamnd merged 2 commits into
mainfrom
reference
Aug 19, 2026
Merged

Generate the API reference from the declarations that ship#13
tamnd merged 2 commits into
mainfrom
reference

Conversation

@tamnd

@tamnd tamnd commented Aug 19, 2026

Copy link
Copy Markdown
Owner

The reference item of the client scorecard, for this client: a generated API reference, published with the release rather than written by hand beside it.

node tools/reference.mjs <directory>, or npm run reference, builds every exported name with its signature and what its doc comment says, out of the declarations this package publishes. The release builds the same pages from the version it is about to publish and uploads them, so the reference a release hands over is about that release and not about whatever the tree looked like when somebody last edited a page.

Why not api-documenter

It was the obvious pick and it was tried first. api-extractor already runs here for the stability report, so its doc model would have meant one reader of the public surface instead of two, and api-documenter turns that model into markdown with no extra configuration at all.

It is missing conn.stream(...) and await using. Both reach the type of a connection through the declare module block in zudb.d.cts, and api-extractor does not follow a module augmentation. A reference whose Connection page has no stream is a reference that sends a reader to cursor, which is the pull underneath it and the thing almost nobody should be holding. So the generator here is typedoc, which reads the declarations with the TypeScript compiler and carries both.

Worth saying plainly: the same gap is in etc/zudb.api.md, so the stability gate does not see those two members either. That is a defect in the report and not in this package, and closing it means declaring Connection some way other than by augmentation, which changes what a consumer's compiler sees for a name that is also a value. It is left alone here and it is worth its own change.

The two checks

A generated reference fails quietly. It builds, it looks finished, and a reader finds out.

Every name zudb.cjs exports has to be documented, and documented as a value rather than as a type. That catches the declarations going missing for a name a program can still require, which is the failure this package is shaped to have: the addon and the declarations come out of one Rust crate and are published as two files.

The two augmented members have to be on the Connection page. That is the check on the choice of generator: if this ever becomes one that reads the whole file and misses them, it fails here rather than shipping.

test/reference.test.mjs runs the tool and reads the page it produced, on every cell of the matrix.

tamnd added 2 commits August 19, 2026 10:53
A reference written by hand beside the code is wrong by the second
release, and wrong in the way that costs the most: it looks maintained.
So this one is generated, from the declarations the published package
carries, and the release builds it from the version it is publishing.

typedoc rather than api-documenter, which was the obvious pick: it is
the other half of the api-extractor toolchain, api-extractor already
runs here for the stability report, and reusing its doc model would have
meant one reader of the surface instead of two. It was tried first and
it is missing `conn.stream(...)` and `await using`, because both reach
the type of a connection through the `declare module` in zudb.d.cts and
api-extractor does not follow one. A reference missing the streaming
entry point is a reference that sends a reader to the cursor, so the
generator that reads the declarations with the TypeScript compiler is
the one used here.

The same gap is in etc/zudb.api.md, which means the stability gate does
not see those two members either. That is a defect in the report rather
than in this package, and fixing it means declaring `Connection` some
way other than by augmentation, which changes what a consumer's compiler
sees. Left alone here and worth its own change.

Two checks, because a generated reference fails quietly. Every name
`zudb.cjs` exports has to be documented as a value, which catches types
that went missing for a name a program can still require, and the two
augmented members have to be on the Connection page, which catches the
generator quietly becoming one that reads the file and misses them.
An entry point is a glob, and a backslash in a glob escapes whatever
follows it. So the path the tool computed for its own sibling arrived at
typedoc as `zudb.d.cts` carrying three escapes, matched nothing, and the
run produced a reference with nothing in it. Windows only, which is why
it passed here and failed there.

The checks did their job: fifteen complaints, one per exported name plus
the two augmented members, and a red build rather than an empty page in
a release artifact. They said it at the wrong altitude though, so an
error out of typedoc is now its own failure. A generator that could not
find the file it was pointed at has not produced a thin reference, it
has produced no reference, and the thirteen missing pages are a true
answer to a question nobody asked.
@tamnd
tamnd merged commit c8892b1 into main Aug 19, 2026
29 checks passed
@tamnd
tamnd deleted the reference branch August 19, 2026 04:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant